import { Box, Button, Input, Paper, TextField } from "@mui/material";
import { useSnackbar } from "notistack/dist";
import React, { useEffect, useRef, useState } from "react";
import MyButton from "../../components/MyButton";
import RandomButton from "../../components/RandomButton";
import "./merge.css";
import MergePillar from "./MergePillar";
const MAXHEIGHT = 200;

export default function Merge(props) {
  const [posx, setPosx] = useState([]);
  const [posy, setPosy] = useState([]);
  const [color, setColor] = useState([]);
  const [ipt, setIpt] = useState();
  const [numbers, setNumbers] = useState([]);
  const [tnumbers, setTnumbers] = useState([]);

  const { enqueueSnackbar } = useSnackbar();

  const [isSorting, setIsSorting] = useState(false);
  const { msg, setMsg } = props;
  const mount = useRef(false);
  var tposx = [],
    data = [],
    len,
    tmsg = msg;

  const upd = () => {
    var tpy = [],
      tcl = [],
      tpx = [];
    for (var i in data) {
      tpy[data[i].p] = data[i].posy;
      tcl[data[i].p] = data[i].color;
      tpx[data[i].p] = data[i].nowpos;
    }
    setColor([...tcl]);
    setPosx([...tpx]);
    setPosy([...tpy]);
  };
  useEffect(() => {
    setMsg({
      sentence: "归并排序",
      sT: 0,
      cT: 0,
      tot: 0,
    });
    mount.current = true;
    return () => (mount.current = false);
  }, []);
  const change = async () => {
    if (isSorting) {
      enqueueSnackbar("正在排序中", { variant: "warning" });
      return;
    }
    if (ipt == null) {
      enqueueSnackbar("请输入以英文逗号分隔的正整数", { variant: "error" });
      return;
    }
    var tmp = ipt.split(",").map((val) => +val);
    var mx = 0;

    tposx = [];
    data = [];

    for (var i in tmp) {
      if (isNaN(tmp[i]) || tmp[i] == 0) {
        enqueueSnackbar("请输入以英文逗号分隔的正整数", { variant: "error" });
        return;
      }
      if (tmp[i] > mx) {
        mx = tmp[i];
      }
    }
    setIsSorting(true);

    setNumbers(tmp);
    setTnumbers(tmp.map((val) => (MAXHEIGHT / mx) * val));

    data = tmp.map((val, index) => {
      return {
        p: index,
        posy: 0,
        num: val,
        color: 1,
        nowpos: index,
      };
    });
    upd();
    len = tmp.length;
    // console.log(tmp.length);
    tmsg = { sentence: "归并排序", cT: 0, sT: 0, tot: len };
    if (mount.current) setMsg({ ...tmsg });
    else return;
    await solve(0, len - 1);
    setIsSorting(false);
  };

  const sleep = (time) => {
    return new Promise(function (resolve) {
      setTimeout(resolve, time * props.speed);
    });
  };

  const solve = async (l, r) => {
    if (l == r) return;

    var mid = Math.floor((l + r) / 2);
    await sleep(700);

    for (var i = 0; i < len; ++i) {
      if (i >= l && i <= r) data[i].color = 3;
      else data[i].color = 1;
    }

    upd();

    await solve(l, mid);
    await solve(mid + 1, r);

    // console.log(l, r);

    for (var i = l; i <= r; ++i) {
      data[i].posy = 350;
      data[i].color = 3;
    }

    tmsg = { ...tmsg, sentence: "处理区间[" + l + "," + r + "]" };
    if (mount.current) setMsg({ ...tmsg });
    else return;

    upd();

    await sleep(700);

    var tmp = [],
      cnt = l,
      p1 = l,
      p2 = mid + 1;
    var lst = -1;

    while (p1 <= mid && p2 <= r) {
      data[p1].color = data[p2].color = 2;
      if (lst !== -1) data[lst].color = 4;
      tmsg = {
        ...tmsg,
        cT: tmsg.cT + 1,
        sentence: "比较" + data[p1].num + "和" + data[p2].num,
      };
      if (mount.current) setMsg({ ...tmsg });
      else return;

      upd();

      await sleep(700);

      if (data[p1].num <= data[p2].num) {
        data[p1].nowpos = cnt;
        // data[p1].color = 4;
        data[p1].posy = 0;
        lst = p1;
        tmp[cnt++] = { ...data[p1++] };
        tmsg = {
          ...tmsg,
          sT: tmsg.sT + 1,
          sentence: "选择" + data[p1 - 1].num,
        };
        if (mount.current) setMsg({ ...tmsg });
        else return;
        // console.log(p1, cnt);
      } else {
        data[p2].nowpos = cnt;
        // data[p2].color = 4;
        data[p2].posy = 0;
        lst = p2;
        tmp[cnt++] = { ...data[p2++] };
        tmsg = {
          ...tmsg,
          sT: tmsg.sT + 1,
          sentence: "选择" + data[p2 - 1].num,
        };
        if (mount.current) setMsg({ ...tmsg });
        else return;
      }

      upd();
      await sleep(700);
    }

    if (lst !== -1) data[lst].color = 4;

    upd();
    await sleep(700);

    while (p1 <= mid) {
      data[p1].nowpos = cnt;
      // data[p1].color = 4;
      data[p1].posy = 0;
      tmp[cnt++] = data[p1++];
      tmsg = {
        ...tmsg,
        sT: tmsg.sT + 1,
        sentence: "选择" + data[p1 - 1].num,
      };
      if (mount.current) setMsg({ ...tmsg });
      else return;
      upd();
      await sleep(700);
      data[p1 - 1].color = 4;
    }

    while (p2 <= r) {
      data[p2].nowpos = cnt;
      data[p2].color = 4;
      data[p2].posy = 0;
      tmp[cnt++] = { ...data[p2++] };
      tmsg = {
        ...tmsg,
        sT: tmsg.sT + 1,
        sentence: "选择" + data[p2 - 1].num,
      };
      if (mount.current) setMsg({ ...tmsg });
      else return;
      upd();

      await sleep(700);
      data[p2 - 1].color = 4;
    }

    upd();
    await sleep(700);

    for (var i = l; i <= r; ++i) data[i] = { ...tmp[i] };
    for (var i = l; i <= r; ++i) {
      data[i].color = 1;
    }

    upd();
    await sleep(700);
  };

  return (
    <Paper sx={{ height: "620px" }} elevation={3}>
      <div className="main">
        <div className="Inner">
          {posx.map((val, index) => {
            return (
              <MergePillar
                number={numbers[index]}
                color={color[index]}
                pos={val}
                height={tnumbers[index]}
                posy={posy[index]}
              />
            );
          })}
        </div>
        <div
          style={{
            width: "100%",
            display: "flex",
            flexDirection: "column",
            alignItems: "center",
            marginTop: "20px",
          }}
        >
          <TextField
            // label="数据"
            value={ipt}
            size="small"
            helperText="*请输入英文逗号隔开的正整数"
            onChange={(e) => {
              setIpt(e.target.value);
            }}
          />
          <Box sx={{ marginTop: 1, display: "flex", flexDirection: "row" }}>
            <MyButton loading={isSorting} variant="contained" onClick={change}>
              {isSorting ? "正在排序 " : "提交"}
            </MyButton>
            <RandomButton loading={isSorting} setData={setIpt} />
            {/* <Button
            sx={{ marginLeft: 3 }}
            variant="contained"
            onClick={ceshi}
            // onClick={() => solve(0, numbers.length - 1)}
          >
            排序
          </Button> */}
          </Box>
        </div>
      </div>
    </Paper>
  );
}

/*

0,1,2
0,1,2

1,0,2
1,0,2

1,2,0

2,0,1

2,3,1

2,1,3
1,2,0
*/
